/**
 * Author: Daniel Michalski
 * Date: 04.02.13
 */

class CallMe {
    void call(String msg) {
        System.out.print("[" + msg);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            System.out.println("Przerwano");
        }
        System.out.println("]");
    }
}

class Caller implements Runnable {
    String msg;
    CallMe target;
    Thread t;

    public Thread getT() {
        return t;
    }

    public Caller(CallMe targ, String s) {
        msg = s;
        target = targ;

        t = new Thread(this);
        t.start();
    }

    @Override
    public void run() {
        synchronized (target) {
            target.call(msg);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        CallMe target = new CallMe();
        Caller ob1 = new Caller(target, "Witaj");
        Caller ob2 = new Caller(target, "Zsynchronizowany");
        Caller ob3 = new Caller(target, "Swiecie");

        try {
            ob1.getT().join();
            ob2.getT().join();
            ob3.getT().join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
